package com.ibeetl.admin.aod.web;

import com.ibeetl.admin.aod.entity.AodIndustry;
import com.ibeetl.admin.aod.entity.AodIndustryData;
import com.ibeetl.admin.aod.entity.DieImportTask;
import com.ibeetl.admin.aod.service.AodIndustryDataService;
import com.ibeetl.admin.aod.service.AodIndustryService;
import com.ibeetl.admin.aod.service.excel.processor.data.AodIndustryDataDbFilterProcessor;
import com.ibeetl.admin.aod.service.excel.processor.data.AodIndustryDataExcelFilterProcessor;
import com.ibeetl.admin.aod.service.excel.processor.data.AodIndustryDataExcelCompareProcessor;
import com.ibeetl.admin.aod.util.DateUtils;
import com.ibeetl.admin.aod.web.dto.AodIndustryDataDto;
import com.ibeetl.admin.aod.web.dto.AodIndustryDataExportDto;
import com.ibeetl.admin.aod.web.query.AodIndustryDataExportQuery;
import com.ibeetl.admin.aod.web.query.AodIndustryDataNonQuery;
import com.ibeetl.admin.aod.web.query.AodIndustryDataQuery;
import com.ibeetl.admin.aod.web.query.FilterQuery;
import com.ibeetl.admin.core.annotation.Function;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.file.FileItem;
import com.ibeetl.admin.core.file.FileService;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.*;
import com.ibeetl.admin.core.web.JsonResult;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.beetl.sql.core.engine.PageQuery;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.Map;

/**
 * AodIndustryData 接口
 */
@Controller
public class AodIndustryDataController{

    private final Log log = LogFactory.getLog(this.getClass());

    private static final String MODEL = "/aod/aodIndustryData";


    @Autowired
    protected AodIndustryDataService aodIndustryDataService;

    @Autowired
    protected AodIndustryDataExcelCompareProcessor aodIndustryDataExcelCompareProcessor;

    @Autowired
    protected AodIndustryDataExcelFilterProcessor aodIndustryDataExcelFilterImportProcessor;

    @Autowired
    protected AodIndustryDataDbFilterProcessor aodIndustryDataDbFilterProcessor;

    @Autowired
    protected FileService fileService;

    @Autowired
    protected CorePlatformService corePlatformService;

    @Autowired
    protected AodIndustryService aodIndustryService;

    /* 页面 */
    @GetMapping(MODEL + "/index.do")
    @Function("aodIndustryData.query")
    @ResponseBody
    public ModelAndView index() {
        ModelAndView view = new ModelAndView("/aod/aodIndustryData/index.html") ;
        view.addObject("search", AodIndustryDataQuery.class.getName());
        return view;
    }

    @GetMapping(MODEL + "/edit.do")
    @Function("aodIndustryData.edit")
    @ResponseBody
    public ModelAndView edit(Integer id) {
        ModelAndView view = new ModelAndView("/aod/aodIndustryData/edit.html");
        AodIndustryData aodIndustryData = aodIndustryDataService.queryById(id);
        view.addObject("aodIndustryData", aodIndustryData);
        return view;
    }

    @GetMapping(MODEL + "/add.do")
    @Function("aodIndustryData.add")
    @ResponseBody
    public ModelAndView add() {
        ModelAndView view = new ModelAndView("/aod/aodIndustryData/add.html");
        return view;
    }

    @PostMapping(MODEL + "/list.json")
    @Function("aodIndustryData.query")
    @ResponseBody
    public JsonResult<PageQuery> list(AodIndustryDataQuery condtion) {
        PageQuery page = condtion.getPageQuery();
        aodIndustryDataService.queryByCondition(page);
        return JsonResult.success(page);
    }

    /**
     * 导出数据页面 主页
     * @return
     */
    @GetMapping(MODEL + "/exportIndex.do")
    @Function("aodIndustryData.query")
    @ResponseBody
    public ModelAndView exportIndex() {
        ModelAndView view = new ModelAndView("/aod/aodIndustryData/exportIndex.html") ;
        view.addObject("search", AodIndustryDataExportQuery.class.getName());
        return view;
    }

    /**
     * 导出数据页面 分页查询
     * @param condtion
     * @return
     */
    @PostMapping(MODEL + "/exportList.json")
    @Function("aodIndustryData.query")
    @ResponseBody
    public JsonResult<PageQuery> exportList(AodIndustryDataExportQuery condtion) {
        if (null == condtion.getIndustryId()) {
            // 默认查询的是 无行业数据
            condtion.setIndustryId(AodIndustryData.NON_INDUSTRY_ID);
        }
        AodIndustry aodIndustry = aodIndustryService.queryById(condtion.getIndustryId());
        if (null == aodIndustry) {
            throw new PlatformException("找不到对应的行业类别表");
        }
        condtion.setTableName(aodIndustry.getIndustryTable());

        PageQuery page = condtion.getPageQuery();
        aodIndustryDataService.queryExportByCondition(page);
        return JsonResult.success(page);
    }

    private String fileEncoding = "gbk";

    /**
     * 导出数据页面 按照条件导出EXCEL
     * @param response
     * @param condition
     * @return
     */
    @PostMapping(MODEL + "/excel/exportExcelAll.json")
    @Function("aodIndustryData.export")
    @ResponseBody
    public JsonResult<String> exportExcelAll(HttpServletResponse response, AodIndustryDataExportQuery condition) {

        BufferedWriter bufferedWriter = null;

        try {
            if (null == condition.getIndustryId()) {
                // 默认查询的是 无行业数据
                condition.setIndustryId(AodIndustryData.NON_INDUSTRY_ID);
            }
            AodIndustry aodIndustry = aodIndustryService.queryById(condition.getIndustryId());
            if (null == aodIndustry) {
                throw new PlatformException("找不到对应的行业类别表");
            }
            condition.setTableName(aodIndustry.getIndustryTable());

            // 目前是全部取出来,可能得改成多线程取数
            PageQuery<AodIndustryData> page = condition.getPageQuery();
            //取出全部符合条件的
            page.setPageSize(Integer.MAX_VALUE);
            page.setPageNumber(1);
            page.setTotalRow(Integer.MAX_VALUE);
            //本次导出需要的数据
            List<AodIndustryDataExportDto> list = aodIndustryDataService.queryExportByCondition(page).getList();

            // 写成CSV文件
            String header = "行业名称,账号,手机号码,入库时间,发送时间,发送内容,回复内容,回复时间,省份,城市,运营商,标签,等级";

            String saveFilePath = System.getProperty("user.dir") + "/filesystem/temp/";
//
//            FileUtils.forceMkdir(new File(saveFilePath));

            FileItem item = fileService.createFileTemp("industryData.csv");

            String csvName = item.getOriginalFilaName();

            bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream( saveFilePath + csvName, false), fileEncoding));
            bufferedWriter.write(header + "\r\n");
            StringBuilder content;
            for (AodIndustryDataExportDto aodIndustryDataExportDto : list) {
                content = new StringBuilder();
                content.append(aodIndustryDataExportDto.getIndustryName() + ",")
                        .append(aodIndustryDataExportDto.getAccount() + ",")
                        .append(aodIndustryDataExportDto.getPhoneNumber() + ",")
                        .append(DateUtils.formatToDateTime(aodIndustryDataExportDto.getAddTime()) + ",")
                        .append(DateUtils.formatToDateTime(aodIndustryDataExportDto.getSendTime()) + ",")
                        .append(aodIndustryDataExportDto.getSendContent() + ",")
                        .append(aodIndustryDataExportDto.getReplyContent() + ",")
                        .append(DateUtils.formatToDateTime(aodIndustryDataExportDto.getReplyTime()) + ",")
                        .append(aodIndustryDataExportDto.getProvince() + ",")
                        .append(aodIndustryDataExportDto.getCity() + ",")
                        .append(aodIndustryDataExportDto.getCorp() + ",")
                        .append(aodIndustryDataExportDto.getLabel() + ",")
                        .append(aodIndustryDataExportDto.getLevel());
                bufferedWriter.write(content.toString() + "\r\n");
            }
            return  JsonResult.success(item.getPath());
        } catch (Exception e) {
            log.error("导出行业数据失败",e);
        } finally {
            if (null != bufferedWriter) {
                try {
                    bufferedWriter.flush();
                    bufferedWriter.close();
                } catch (Exception e) {
                    log.error("关闭流出错",e);
                }
            }
        }
        return JsonResult.success("导出失败");
    }

    /**
     * 无数据标签量页面 主页
     * @return
     */
    @GetMapping(MODEL + "/nonIndex.do")
    @Function("aodIndustryData.query")
    @ResponseBody
    public ModelAndView nonIndex() {
        ModelAndView view = new ModelAndView("/aod/aodIndustryData/nonIndex.html") ;
        view.addObject("search", AodIndustryDataNonQuery.class.getName());
        return view;
    }

    /**
     * 无数据标签量页面 分页查询
     * @param condition
     * @return
     */
    @PostMapping(MODEL + "/nonList.json")
    @Function("aodIndustryData.query")
    @ResponseBody
    public JsonResult<PageQuery> nonList(AodIndustryDataNonQuery condition) {
        PageQuery page = condition.getPageQuery();
        aodIndustryDataService.queryNonByCondition(page);
        return JsonResult.success(page);
    }

    @PostMapping(MODEL + "/add.json")
    @Function("aodIndustryData.add")
    @ResponseBody
    public JsonResult add(@Validated(ValidateConfig.ADD.class)AodIndustryData aodIndustryData) {
        aodIndustryDataService.save(aodIndustryData);
        return new JsonResult().success();
    }

    @PostMapping(MODEL + "/update.json")
    @Function("aodIndustryData.update")
    @ResponseBody
    public JsonResult<String> update(@Validated(ValidateConfig.UPDATE.class)  AodIndustryData aodIndustryData) {
        boolean success = aodIndustryDataService.update(aodIndustryData);
        if (success) {
            return new JsonResult().success();
        } else {
            return JsonResult.failMessage("保存失败");
        }
    }

    @GetMapping(MODEL + "/view.json")
    @Function("aodIndustryData.query")
    @ResponseBody
    public JsonResult<AodIndustryData> queryInfo(Integer id) {
        AodIndustryData aodIndustryData = aodIndustryDataService.queryById( id);
        return  JsonResult.success(aodIndustryData);
    }

    @PostMapping(MODEL + "/delete.json")
    @Function("aodIndustryData.delete")
    @ResponseBody
    public JsonResult delete(String ids) {
        if (ids.endsWith(",")) {
            ids = StringUtils.substringBeforeLast(ids, ",");
        }
        List<Long> idList = ConvertUtil.str2longs(ids);
        aodIndustryDataService.batchDelAodIndustryData(idList);
        return new JsonResult().success();
    }
    
    @PostMapping(MODEL + "/excel/export.json")
    @Function("aodIndustryData.export")
    @ResponseBody
    public JsonResult<String> export(HttpServletResponse response,AodIndustryDataQuery condtion) {
        /**
         * 1)需要用你自己编写一个的excel模板
         * 2)通常excel导出需要关联更多数据，因此aodIndustryDataService.queryByCondition方法经常不符合需求，需要重写一个为模板导出的查询
         * 3)参考ConsoleDictController来实现模板导入导出
         */
        String excelTemplate ="excelTemplates/aod/aodIndustryData/你的excel模板文件名字.xls";
        PageQuery<AodIndustryData> page = condtion.getPageQuery();
        //取出全部符合条件的
        page.setPageSize(Integer.MAX_VALUE);
        page.setPageNumber(1);
        page.setTotalRow(Integer.MAX_VALUE);
        //本次导出需要的数据
        List<AodIndustryData> list =aodIndustryDataService.queryByCondition(page).getList();

        try(InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(excelTemplate)) {
            if(is==null) {
                throw new PlatformException("模板资源不存在："+excelTemplate);
            }
            FileItem item = fileService.createFileTemp("AodIndustryData_"+DateUtil.now("yyyyMMddHHmmss")+".xls");
            OutputStream os = item.openOutpuStream();
            Context context = new Context();
            context.putVar("list", list);
            JxlsHelper.getInstance().processTemplate(is, os, context);
            os.close();
            //下载参考FileSystemContorller
            return  JsonResult.success(item.getPath());
        } catch (IOException e) {
            throw new PlatformException(e.getMessage());
        }
        
    }
    
    @PostMapping(MODEL + "/excel/import.do")
    @Function("aodIndustryData.import")
    @ResponseBody
    public JsonResult importExcel(@RequestParam("files") MultipartFile[] files) throws Exception {

        CoreUser coreUser = corePlatformService.getCurrentUser();

        try {
            aodIndustryDataExcelCompareProcessor.process(files, coreUser);
            return JsonResult.success();
        } catch (Exception e) {
            log.error("导入行业关键词出错",e);
            return JsonResult.failMessage(e.getMessage());
        }

    }

    /**
     * EXCEL筛查行业数据
     * @param file
     * @param filterQuery
     * @return
     * @throws Exception
     */
    @PostMapping(MODEL + "/excel/filterImport.do")
    @Function("aodIndustryData.filterImport")
    @ResponseBody
    public JsonResult filterImportExcel(@RequestParam("file") MultipartFile file, FilterQuery filterQuery) throws Exception {

        CoreUser coreUser = corePlatformService.getCurrentUser();

        try {
            aodIndustryDataExcelFilterImportProcessor.process(file, filterQuery, coreUser);
            return JsonResult.success();
        } catch (Exception e) {
            log.error("EXCEL筛查行业数据出错",e);
            return JsonResult.failMessage(e.getMessage());
        }

    }

    @PostMapping(MODEL + "/dbFilter.do")
    @Function("aodIndustryData.dbFilter")
    @ResponseBody
    public JsonResult dbFilter(FilterQuery filterQuery) {

        CoreUser coreUser = corePlatformService.getCurrentUser();

        try {
            aodIndustryDataDbFilterProcessor.process(filterQuery, coreUser);
            return JsonResult.success();
        } catch (Exception e) {
            log.error("数据库筛查行业数据出错",e);
            return JsonResult.failMessage(e.getMessage());
        }

    }

}
